package com.mms.entity.tag;

import com.mms.entity.dao.HibernateDao;
import com.mms.entity.dao.MybatisDao;
import com.mms.entity.model.Page;
import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.ContextLoader;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
import javax.servlet.jsp.tagext.DynamicAttributes;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by dangz on 2017-5-23.
 */
public class PagerTag extends BodyTagSupport implements DynamicAttributes {
    private static final Logger logger = LoggerFactory.getLogger(PagerTag.class);
    private static final long serialVersionUID = -3007463448279167711L;
    private String sql;
    private String hql;
    private String statement;
    private final Map<String, Object> map = new HashMap();
    private String size = "0";
    private String page = "1";
    private String id;

    public PagerTag() {
    }

    public void setDynamicAttribute(String uri, String localName, Object value) throws JspException {
        this.map.put(localName, value);
    }

    public int doStartTag() throws JspException {
        Page pager = new Page();
        Object list = new ArrayList();

        try {
            ApplicationContext appCtx = ContextLoader.getCurrentWebApplicationContext();
            int totalCount = 0;
            boolean var5 = false;

            int tmppage;
            try {
                tmppage = Integer.parseInt(this.page) < 1?1:Integer.parseInt(this.page);
            } catch (Exception var13) {
                tmppage = 1;
            }

            boolean var6 = true;

            int tmpsize;
            try {
                tmpsize = Integer.parseInt(this.size);
            } catch (Exception var12) {
                tmpsize = 15;
            }

            int pageCount = 1;
            HibernateDao hibernateDao;
            int start;
            if(StringUtils.isNotEmpty(this.hql)) {
                hibernateDao = (HibernateDao)appCtx.getBean("hibernateDao");
                totalCount = hibernateDao.getCount(this.hql).intValue();
                if(tmpsize > 0) {
                    pageCount = totalCount % tmpsize == 0?totalCount / tmpsize:totalCount / tmpsize + 1;
                    pageCount = pageCount <= 0?1:pageCount;
                }

                if(tmppage > pageCount) {
                    tmppage = pageCount;
                }

                if(totalCount > 0) {
                    start = (tmppage - 1) * tmpsize;
                    start = start + tmpsize;
                    list = hibernateDao.find(start, start, this.hql, new Object[0]);
                }
            } else if(StringUtils.isNotEmpty(this.sql)) {
                hibernateDao = (HibernateDao)appCtx.getBean("hibernateDao");
                totalCount = ((Number)hibernateDao.createSQLQuery("SELECT COUNT(*) FROM (" + this.sql + ") t").uniqueResult()).intValue();
                if(tmpsize > 0) {
                    pageCount = totalCount % tmpsize == 0?totalCount / tmpsize:totalCount / tmpsize + 1;
                    pageCount = pageCount <= 0?1:pageCount;
                }

                if(tmppage > pageCount) {
                    tmppage = pageCount;
                }

                Query query = hibernateDao.createSQLQuery(this.sql).setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
                query.setFirstResult((tmppage - 1) * tmpsize);
                query.setMaxResults(tmpsize);
                if(totalCount > 0) {
                    list = query.list();
                }
            } else if(StringUtils.isNotEmpty(this.statement)) {
                MybatisDao ibatisDao = (MybatisDao)appCtx.getBean("ibatisDao");
                Map map1 = (Map)ibatisDao.queryForObject(this.statement + "Count", this.map);
                totalCount = ((Number)map1.get("CT")).intValue();
                if(tmpsize > 0) {
                    pageCount = totalCount % tmpsize == 0?totalCount / tmpsize:totalCount / tmpsize + 1;
                    pageCount = pageCount <= 0?1:pageCount;
                }

                if(tmppage > pageCount) {
                    tmppage = pageCount;
                }

                start = (tmppage - 1) * tmpsize + 1;
                int end = start + tmpsize - 1;
                this.map.put("start", Integer.valueOf(start));
                this.map.put("end", Integer.valueOf(end));
                if(totalCount > 0) {
                    list = ibatisDao.queryForList(this.statement, this.map);
                }
            }

            pager.setPageNo(Integer.valueOf(tmppage));
            pager.setPageSize(Integer.valueOf(tmpsize));
            pager.setPageCount((long)pageCount);
            pager.setTotalCount((long)totalCount);
        } catch (Exception var14) {
            logger.error("", var14);
        }

        pager.setList((List)list);
        this.pageContext.setAttribute(this.id, pager);
        return 0;
    }

    public void doInitBody() throws JspException {
        super.doInitBody();
    }

    public int doEndTag() throws JspException {
        return 6;
    }

    public String getId() {
        return this.id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getHql() {
        return this.hql;
    }

    public void setHql(String hql) {
        this.hql = hql;
    }

    public String getSql() {
        return this.sql;
    }

    public void setSql(String sql) {
        this.sql = sql;
    }

    public String getSize() {
        return this.size;
    }

    public void setSize(String size) {
        this.size = size;
    }

    public String getPage() {
        return this.page;
    }

    public void setPage(String page) {
        this.page = page;
    }

    public String getStatement() {
        return this.statement;
    }

    public void setStatement(String statement) {
        this.statement = statement;
    }
}
